/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.web.bean;

import com.jb.faces.context.FacesContext;
import com.jb.web.application.PageSecurityException;
import com.jb.web.bean.inspector.GeneralWizard;
import com.jb.web.bean.inspector.OptionPropertyEditor;
import com.jb.web.context.WebContext;


/**
 * Container that can be placed in any location on the screen. Sets it position style
 *
 *
 * When sets to absolute, top, left are the coordinates relative to the browser window. Value z
 * index will be used to set its layer. A panel with a larger number will be placed on top of ones
 * with lower number.  At runtime, this pannel can be moved around as well if a flag is set for
 * the page.
 */
public class FloatPanel extends Region {
    static final long serialVersionUID = 123123L;

    public void setEmbedded(String param) {
        this.embedded = param;
    }

    public String getEmbedded() {
        return embedded;
    }

    static {
        publish(FloatPanel.class, STYLE, "ZIndex");
        publish(FloatPanel.class, STYLE, "position",
            new OptionPropertyEditor("static: ,None;absolute,Absolute;relative,Relative;fixed,Fixed;"));
        
        publish(FloatPanel.class, GENERAL, "embedded");
        publish(FloatPanel.class, STYLE, "left");
        publish(FloatPanel.class, STYLE, "top");

        publish(FloatPanel.class, GENERAL, "draggable");
        publish(FloatPanel.class, GENERAL, "resizable");
        publish(FloatPanel.class, GENERAL, "dragWithin");

        publish(FloatPanel.class, EVENT_HANDLER, "onDrag");
        publish(FloatPanel.class, EVENT_HANDLER, "onDrop");

        publish(FloatPanel.class, EVENT_HANDLER, "onResize");
        publish(FloatPanel.class, GENERAL, "cloneOnDrag");
            
    }
    
    static
    {
        registerWizard(FloatPanel.class, FloatPanel.ContainerWizard.class);
    }
    
    public static class ContainerWizard extends GeneralWizard
    {
        public ContainerWizard() {
            this.setType(FloatPanel.class.getName());
            this.setPageName("ContainerWizard");
            this.setPanelName("containerWizard");   
        }
    }

    //element name with which this element with be allowed to drag
    private String dragWithin;
    private String left;
    private String onDrag;
    private String onDrop;
    private String onResize; //called when
    private String position;
    private String top;
    private String zIndex;
    private boolean cloneOnDrag;
    private boolean draggable;
    private boolean resizable;
    private String embedded;

    public void setCloneOnDrag(boolean cloneOnDrag) {
        this.cloneOnDrag = cloneOnDrag;
    }

    public boolean isCloneOnDrag() {
        return cloneOnDrag;
    }

    public void setDragWithin(String dragWithin) {
        this.dragWithin = dragWithin;
    }

    public String getDragWithin() {
        return dragWithin;
    }

    public BaseComponent getDescendantByClientId(String pClientId) {
        BaseComponent comp = super.getDescendantByClientId(pClientId);
        Page page = (Page) getEmbeddedPage();

        if ((comp == null) && (page != null)) {
            return page.getDescendantByClientId(pClientId);
        } else {
            return comp;
        }
    }

    public boolean updateModel(FacesContext pCtx) {
        super.updateModel(pCtx);

        //if(pCtx.isRunTime())
        Page page = (Page) getEmbeddedPage();

        if (page != null) {
            page.updateModel(pCtx);
        }

        return true;
    }

    public void updateView(WebContext pCtx) {
        super.updateView(pCtx);

        if (pCtx.isRunTime()) {
            Page page = (Page) getEmbeddedPage();

            if (page != null) {
                page.updateView(pCtx);
            }
        }
    }

    public BaseComponent getDescendantById(String pName) {
        BaseComponent comp = super.getDescendantById(pName);
        Page page = (Page) getEmbeddedPage();

        if ((comp == null) && (page != null)) {
            return page.getDescendantById(pName);
        } else {
            return comp;
        }
    }    public void setDraggable(boolean draggable) {
        this.draggable = draggable;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean isDraggable() {
        return draggable;
    }

    /**
     * DOCUMENT ME!
     *
     * @param left DOCUMENT ME!
     */
    public void setLeft(String left) {
        this.left = left;
    }

    public Object getEmbeddedPage() {
        if ((embedded == null) || (embedded.length() == 0)) {
            return null;
        }

        if (getFacesContext() != null) {
            WebContext ctx = (WebContext) getFacesContext();

            try {
                Page page = ctx.getSession().getPage(ctx, embedded, true);

                if (page == null) {
                    ctx.addErrorMessage(this, "embedded page " + embedded + " not found");

                    return null;
                }

                return page;
            } catch (PageSecurityException e) {
                //
            }
        }

        return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getLeft() {
        return left;
    }

    public void setOnDrag(String onDrag) {
        this.onDrag = onDrag;
    }

    public String getOnDrag() {
        return onDrag;
    }

    public void setOnDrop(String onDrop) {
        this.onDrop = onDrop;
    }

    public String getOnDrop() {
        return onDrop;
    }

    public void setOnResize(String onResize) {
        this.onResize = onResize;
    }

    public String getOnResize() {
        return onResize;
    }
    
    public void setPosition(String pPosition) {
        this.position = pPosition;
    }

    public String getPosition() {
        return position;
    }

    public String getPositionStyle() {
        if ((position == null) || (position.trim().length() == 0)) {
            return "";
        }

        return com.jb.web.model.css.Style.addProperty("z-Index", getZIndex(), null) +
        com.jb.web.model.css.Style.addProperty("left", getLeft(), null) +
        com.jb.web.model.css.Style.addProperty("top", getTop(), null) +
        com.jb.web.model.css.Style.addProperty("float", getFloatStyle(), null) +
        com.jb.web.model.css.Style.addProperty("position", position, null);
    }

    /**
     * DOCUMENT ME!
     *
     * @param resizable DOCUMENT ME!
     */
    public void setResizable(boolean resizable) {
        this.resizable = resizable;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean isResizable() {
        return resizable;
    }

    /**
      * DOCUMENT ME!
      *
      * @param pCtx DOCUMENT ME!
      *
      * @return DOCUMENT ME!
      */
    public String getStyle(WebContext pCtx) {
        return super.getStyle(pCtx) + getPositionStyle();
    }

    /**
     * DOCUMENT ME!
     *
     * @param top DOCUMENT ME!
     */
    public void setTop(String top) {
        this.top = top;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getTop() {
        return top;
    }

    /**
     * DOCUMENT ME!
     *
     * @param zIndex DOCUMENT ME!
     */
    public void setZIndex(String zIndex) {
        this.zIndex = zIndex;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getZIndex() {
        return zIndex;
    }

    protected void merge(WebContext pCtx, BaseComponent uiComponent) {
        if ((uiComponent == null) || !(uiComponent instanceof FloatPanel)) {
            return;
        }

        FloatPanel fp = (FloatPanel) uiComponent;
        left = fp.left;
        top = fp.top;
        setWidth(fp.getWidth());
        setHeight(fp.getHeight());
        zIndex = fp.zIndex;
    }
}
